#ifndef XPM_DOC_MODEL_SDF_REIFICATION_H
#define XPM_DOC_MODEL_SDF_REIFICATION_H

#include <string>
#include "model/XpmTermBlock.h"
using namespace std;
// reification types
#define SDF_NULL '\0'
#define SDF_STRING '\1'
#define SDF_NUMBER '\2'
#define SDF_TRUE '\3'
#define SDF_FALSE '\4'

namespace xpm {
	
	class SDFReification {
	public:		
		typedef TermIter iterator;
		SDFReification():_termblock(0), _type(SDF_NULL) {}
		SDFReification(wstring sdf_string):_termblock(0), _type(SDF_STRING), _sdf_string(sdf_string) {}
		SDFReification(float sdf_number):_termblock(0), _type(SDF_NUMBER), _sdf_number(sdf_number) {}
		SDFReification(bool sdf_bool):_termblock(0) { _type = sdf_bool ? SDF_TRUE: SDF_FALSE ;}
		SDFReification::iterator begin();
		SDFReification::iterator end();
		int type();
		void set_type(int type);
		// apis
		wstring as_string();
		void set_string(wstring string);
		float as_number();
		void set_number(float number);
		bool as_bool();		
		void set_bool(bool boolvalue);		
		bool empty();
		int size();
		void clear();
		void append_literals(wstring literals);	
		void append_atom_sign(wstring siginifer, conex::Term* siginified);	
		void append_map(int pos, wstring siginifer, conex::Term* siginified);	
	private:
		wstring _sdf_string;
		float _sdf_number;
		int _type;
		XpmTermBlock _termblock;
	};
	inline void SDFReification::set_type(int type) {
		switch(type) {
		case SDF_NUMBER:
		case SDF_STRING:
		case SDF_TRUE:
		case SDF_FALSE:
		case SDF_NULL:
			_type = type;
		default:
			_type = SDF_NULL;
		}
	}
	inline int SDFReification::size() {
		return _termblock.size();
	}
	inline bool SDFReification::empty() {
		if (size() == 0)
			return true;
		else
			return false;
	}
	inline void SDFReification::clear() {
		_sdf_number = 0;
		_sdf_string = L"";
		_termblock.clear();
	}
	inline wstring SDFReification::as_string() {
		return _sdf_string;
	}
	inline void SDFReification::set_string(wstring str) {
		_sdf_string = str;
		_termblock.clear();
		_type = SDF_STRING;
	}
	inline float SDFReification::as_number() {
		return _sdf_number;
	}
	inline void SDFReification::set_number(float num) {
		_sdf_number = num;
		_termblock.clear();
		_type = SDF_NUMBER;
	}
	inline bool SDFReification::as_bool() {
		return _type == SDF_TRUE ? true : false;
	}
	inline void SDFReification::set_bool(bool boolvalue) {
        _termblock.clear();
		_type = boolvalue == true ? SDF_TRUE : SDF_FALSE;
	}
	inline int SDFReification::type() {
		return _type;
	}
	inline SDFReification::iterator SDFReification::begin() {
		return _termblock.GetTerms().begin();
	}
	inline SDFReification::iterator SDFReification::end() {
		return _termblock.GetTerms().end();
	}
	inline void SDFReification::append_literals(wstring literals) {
		if(_type == SDF_STRING) {
			_sdf_string.append(literals);
		}
	}
	inline void SDFReification::append_atom_sign(wstring text, conex::Term* term) {
		if (_type == SDF_STRING) {
			int startpos = _sdf_string.size();
			_termblock.AppendTermRange(startpos, text, term);
			_sdf_string.append(text);
		}
	}
	inline void SDFReification::append_map(int pos, wstring text, conex::Term* term) {
		if (_type == SDF_STRING) {
			_termblock.AppendTermRange(pos, text, term);
		}
	}
}

#endif